"""
发布相关数据模型
"""
from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, Enum, ForeignKey, JSON
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import enum
from datetime import datetime

from app.core.database import Base


class ReleaseStatus(str, enum.Enum):
    """发布状态枚举"""
    PENDING = "pending"           # 待发布
    IN_PROGRESS = "in_progress"   # 发布中
    SUCCESS = "success"           # 发布成功
    FAILED = "failed"             # 发布失败
    ROLLED_BACK = "rolled_back"   # 已回滚
    CANCELLED = "cancelled"       # 已取消


class DeploymentStrategy(str, enum.Enum):
    """部署策略枚举"""
    BLUE_GREEN = "blue_green"     # 蓝绿部署
    CANARY = "canary"             # 金丝雀发布
    ROLLING = "rolling"           # 滚动更新
    RECREATE = "recreate"         # 重新创建


class Environment(str, enum.Enum):
    """环境枚举"""
    DEVELOPMENT = "development"   # 开发环境
    TESTING = "testing"           # 测试环境
    STAGING = "staging"           # 预发布环境
    PRODUCTION = "production"     # 生产环境


class Release(Base):
    """发布记录模型"""
    __tablename__ = "releases"
    
    id = Column(Integer, primary_key=True, index=True)
    version = Column(String(50), nullable=False, index=True, comment="版本号")
    description = Column(Text, comment="发布描述")
    environment = Column(Enum(Environment), nullable=False, comment="目标环境")
    strategy = Column(Enum(DeploymentStrategy), nullable=False, comment="部署策略")
    status = Column(Enum(ReleaseStatus), default=ReleaseStatus.PENDING, comment="发布状态")
    
    # 发布配置
    config = Column(JSON, comment="发布配置")
    artifacts = Column(JSON, comment="发布制品信息")
    
    # 时间信息
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), comment="更新时间")
    deployed_at = Column(DateTime(timezone=True), comment="发布时间")
    completed_at = Column(DateTime(timezone=True), comment="完成时间")
    
    # 发布信息
    deployed_by = Column(String(100), comment="发布人")
    approval_by = Column(String(100), comment="审批人")
    approval_at = Column(DateTime(timezone=True), comment="审批时间")
    
    # 回滚信息
    rollback_reason = Column(Text, comment="回滚原因")
    rollback_by = Column(String(100), comment="回滚操作人")
    rollback_at = Column(DateTime(timezone=True), comment="回滚时间")
    rollback_to_version = Column(String(50), comment="回滚目标版本")
    
    # 关联关系
    steps = relationship("ReleaseStep", back_populates="release", cascade="all, delete-orphan")
    health_checks = relationship("HealthCheck", back_populates="release", cascade="all, delete-orphan")
    
    def __repr__(self):
        return f"<Release(id={self.id}, version='{self.version}', status='{self.status}')>"


class ReleaseStep(Base):
    """发布步骤模型"""
    __tablename__ = "release_steps"
    
    id = Column(Integer, primary_key=True, index=True)
    release_id = Column(Integer, ForeignKey("releases.id"), nullable=False)
    step_name = Column(String(100), nullable=False, comment="步骤名称")
    step_order = Column(Integer, nullable=False, comment="步骤顺序")
    
    # 步骤状态
    status = Column(Enum(ReleaseStatus), default=ReleaseStatus.PENDING, comment="步骤状态")
    started_at = Column(DateTime(timezone=True), comment="开始时间")
    completed_at = Column(DateTime(timezone=True), comment="完成时间")
    
    # 步骤详情
    description = Column(Text, comment="步骤描述")
    command = Column(Text, comment="执行命令")
    output = Column(Text, comment="执行输出")
    error_message = Column(Text, comment="错误信息")
    
    # 步骤配置
    config = Column(JSON, comment="步骤配置")
    timeout = Column(Integer, default=300, comment="超时时间(秒)")
    retry_count = Column(Integer, default=0, comment="重试次数")
    max_retries = Column(Integer, default=3, comment="最大重试次数")
    
    # 关联关系
    release = relationship("Release", back_populates="steps")
    
    def __repr__(self):
        return f"<ReleaseStep(id={self.id}, step_name='{self.step_name}', status='{self.status}')>"


class HealthCheck(Base):
    """健康检查模型"""
    __tablename__ = "health_checks"
    
    id = Column(Integer, primary_key=True, index=True)
    release_id = Column(Integer, ForeignKey("releases.id"), nullable=False)
    
    # 检查信息
    check_name = Column(String(100), nullable=False, comment="检查名称")
    check_type = Column(String(50), nullable=False, comment="检查类型")
    endpoint = Column(String(255), comment="检查端点")
    
    # 检查结果
    status = Column(Boolean, comment="检查状态")
    response_time = Column(Integer, comment="响应时间(毫秒)")
    status_code = Column(Integer, comment="HTTP状态码")
    response_body = Column(Text, comment="响应内容")
    error_message = Column(Text, comment="错误信息")
    
    # 时间信息
    checked_at = Column(DateTime(timezone=True), server_default=func.now(), comment="检查时间")
    
    # 配置信息
    config = Column(JSON, comment="检查配置")
    timeout = Column(Integer, default=30, comment="超时时间(秒)")
    retry_count = Column(Integer, default=0, comment="重试次数")
    
    # 关联关系
    release = relationship("Release", back_populates="health_checks")
    
    def __repr__(self):
        return f"<HealthCheck(id={self.id}, check_name='{self.check_name}', status={self.status})>"


class RollbackRecord(Base):
    """回滚记录模型"""
    __tablename__ = "rollback_records"
    
    id = Column(Integer, primary_key=True, index=True)
    
    # 回滚信息
    from_version = Column(String(50), nullable=False, comment="回滚前版本")
    to_version = Column(String(50), nullable=False, comment="回滚目标版本")
    environment = Column(Enum(Environment), nullable=False, comment="环境")
    
    # 回滚状态
    status = Column(Enum(ReleaseStatus), default=ReleaseStatus.PENDING, comment="回滚状态")
    reason = Column(Text, comment="回滚原因")
    
    # 操作信息
    initiated_by = Column(String(100), comment="发起人")
    initiated_at = Column(DateTime(timezone=True), server_default=func.now(), comment="发起时间")
    completed_at = Column(DateTime(timezone=True), comment="完成时间")
    
    # 回滚详情
    steps = Column(JSON, comment="回滚步骤")
    data_backup = Column(Boolean, default=True, comment="是否备份数据")
    backup_location = Column(String(255), comment="备份位置")
    
    # 影响评估
    affected_services = Column(JSON, comment="受影响服务")
    downtime_duration = Column(Integer, comment="停机时间(秒)")
    data_loss_risk = Column(String(50), comment="数据丢失风险")
    
    def __repr__(self):
        return f"<RollbackRecord(id={self.id}, from='{self.from_version}', to='{self.to_version}')>"


class DeploymentConfig(Base):
    """部署配置模型"""
    __tablename__ = "deployment_configs"
    
    id = Column(Integer, primary_key=True, index=True)
    
    # 配置信息
    name = Column(String(100), nullable=False, unique=True, comment="配置名称")
    environment = Column(Enum(Environment), nullable=False, comment="环境")
    strategy = Column(Enum(DeploymentStrategy), nullable=False, comment="部署策略")
    
    # 配置内容
    config = Column(JSON, nullable=False, comment="配置内容")
    is_active = Column(Boolean, default=True, comment="是否激活")
    
    # 时间信息
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), comment="更新时间")
    created_by = Column(String(100), comment="创建人")
    
    # 描述信息
    description = Column(Text, comment="配置描述")
    version = Column(String(20), comment="配置版本")
    
    def __repr__(self):
        return f"<DeploymentConfig(id={self.id}, name='{self.name}', environment='{self.environment}')>"
